package net.zhangyun;

import net.zhangyun.models.*;

import net.zhangyun.utils.MyConsole;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Scheduler;
import reactor.core.scheduler.Schedulers;

@SpringBootApplication
@RestController
public class ReactiveController {

    Scheduler scheduler = Schedulers.boundedElastic();

    public static void main(String[] args) {
        SpringApplication.run(ReactiveController.class, args);
    }

    @GetMapping("/pets")
    public Flux<Pet> listPets() {
        return Flux.just(
                new Pet("Cat", "Miaomiao"),
                new Pet("Dog", "Wangwang")
        );
    }

    @GetMapping("/pets/{name}")
    public Mono<Pet> getPet(@PathVariable String name) {
        return Mono.just(
                new Pet("Animal", name)
        );
    }

    /**
     * Both Spring MVC and Spring WebFlux support annotated controllers,
     * but there is a key difference in the concurrency model
     * and the default assumptions for blocking and threads.
     *
     * In Spring MVC (and servlet applications in general),
     * it is assumed that applications can block the current thread, (for example, for remote calls).
     * For this reason, servlet containers use a large thread pool to absorb potential blocking during request handling.
     *
     * In Spring WebFlux (and non-blocking servers in general),
     * it is assumed that applications do not block.
     * Therefore, non-blocking servers use a small, fixed-size thread pool (event loop workers) to handle requests.
     *
     */

    @PostMapping("/pets")
    public Mono<Pet> createPet(@RequestBody Mono<String> body) {
        return body.publishOn(scheduler)
                .map(b -> {
                    MyConsole.printMessage(b);
                    return new Pet("Animal", "Alien");
                });
    }
}
